package test

import (
	"encoding/json"
    "testing"

	"github.com/iris-contrib/httpexpect/v2"
	"github.com/kataras/iris/v12/httptest"
	"github.com/liuxd6825/dapr-go-ddd-sdk/applog"
	"github.com/liuxd6825/dapr-go-ddd-sdk/daprclient"
	"github.com/liuxd6825/dapr-go-ddd-sdk/ddd"
	"github.com/liuxd6825/dapr-go-ddd-sdk/restapp"

	"github.com/liuxu6825/dapr-go-ddd-example/pkg/cmd-service/infrastructure/register"
)

const (
	EnvName = "dev"
	TenantId = "test"
)

// InitCommand 初始化命令服务测试环境
func InitCommand(eventTypes []restapp.RegisterEventType) {
	config, err := restapp.NewConfigByFile("${search}/config/cmd-config.yaml")
	if err != nil {
		panic(err)
	}

	env, err := config.GetEnvConfig(EnvName)
	if err != nil {
		panic(err)
	}

	daprClient := registerDaprDddClient(env)
	registerEventStorage(env, daprClient)
	registerEventTypes(eventTypes)
	ddd.Init(env.App.AppId)
	applog.Init(daprClient, env.App.AppId, applog.INFO)
}

// registerDaprDddClient 创建dapr客户端
func registerDaprDddClient(env *restapp.EnvConfig) daprclient.DaprDddClient {
	daprClient, err := daprclient.NewDaprDddClient(env.Dapr.GetHost(), env.Dapr.GetHttpPort(), env.Dapr.GetGrpcPort())
	if err != nil {
		panic(err)
	}
	daprclient.SetDaprDddClient(daprClient)
	return daprClient
}

// registerEventStorage 注册事件存储器
func registerEventStorage(env *restapp.EnvConfig, daprClient daprclient.DaprDddClient) {
	for _, pubsubName := range env.Dapr.Pubsubs {
		eventStorage, err := ddd.NewGrpcEventStorage(daprClient, ddd.PubsubName(pubsubName))
		if err != nil {
			panic(err)
		}
		ddd.RegisterEventStorage(pubsubName, eventStorage)
		ddd.RegisterEventStorage("", eventStorage)
	}
}

// registerEventTypes 注册事件类型
func registerEventTypes(eventTypes []restapp.RegisterEventType) {
	for _, t := range eventTypes {
		if err := ddd.RegisterEventType(t.EventType, t.Version, t.NewFunc); err != nil {
			panic(err)
		}
	}
}

// PrintJson 以JSON格式打印
func PrintJson(t *testing.T, title string, data interface{}) error {
	bs, err := json.Marshal(data)
	if err != nil {
		return err
	}
	t.Log(title)
	t.Log(string(bs))
	return nil
}

// CheckResponse 检查HttpStatus，并打印body结果
func CheckResponse(t *testing.T, resp *httpexpect.Response) error {
	raw := resp.Raw()
	if raw.StatusCode != httptest.StatusOK {
		t.Error(raw.StatusCode)
	}
	t.Log(resp.Body().Raw())
	return nil
}
